﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.IO;
using Shoozla.DataModel;
using System.Net;
using System.Drawing;
using System.Windows;

namespace Shoozla
{
    class BatchSearch
    {
        private static List<ManualResetEvent> _events;
        private static object syncRoot = new object();
        private static int _eventIndex = 0;
        private static int EventIndex { set { lock (syncRoot) { _eventIndex = value; }; } get { return _eventIndex; } }

        public static void StartBatchSearch(DirectoryInfo folder)
        {                   
            if (AppModel.CoverSearcher.Initialize())
            {                
                AppModel.LogEntry("Connecting to the WEB....");                
              
                _events = new List<ManualResetEvent>();
                
                foreach (FileInfo f in folder.GetFiles("*.mp3", SearchOption.AllDirectories))
                {
                  
                    AppModel.LogEntry("Read file: " + f.Name);
                    _events.Add(new ManualResetEvent(false));
                    ThreadPool.QueueUserWorkItem(new WaitCallback(SearchCoverThread), (object)new object[] { f, _events.Count - 1 });
                }
                AppModel.LogEntry("Wait...");
                WaitForAll(_events.ToArray());

                WorkDone();
            }

        }

        static void WorkDone()
        {
            string summary = String.Format("Shoozla has finished!\nSummary:\n\tfiles: {0}\n\tcover found: {1} \n\t", App.StatisticLogger.TotalFiles,App.StatisticLogger.FoundCovers);
            AppModel.LogEntry("Done.");
            AppModel.LogEntry(summary);
           // App.CoverStorage.SaveToStorage(@"shoozla.xml");
            AppModel.LogEvent(summary, false, 2);
            //MessageBox.Show(summary, "Shoozla, Background search", MessageBoxButton.OK,MessageBoxImage.Information);
        }

        static bool WaitForAll(ManualResetEvent[] events)
        {
            bool result = false;
            try
            {
                if (events != null)
                {
                    for (; EventIndex < events.Length; EventIndex++)
                    {
                        events[EventIndex].WaitOne();
                    }
                    result = true;
                }
            }
            catch
            {
                result = false;
            }
            return result;
        } 

        private static void SearchCoverThread(object o)
        {
            object[] par = o as object[];
            int index = (int)par[1];
            SearchCover(par[0] as FileInfo);
            lock (syncRoot)
            {
                _events[index].Set();
            }

        }

        private static void SearchCover(FileInfo f)
        {
            try
            {
                IMP3Processor mp3Processor = new IDSharpProcessor();
                Mp3File song = mp3Processor.ReadID3Tag(f,false);
                if (song.HasCover)
                    return;

                Uri cover = AppModel.CoverSearcher.FindSingleCover(song);
                if (cover != null)
                {                  
                    WebRequest req = WebRequest.Create(cover);
                    WebResponse response = req.GetResponse();
                    Stream stream = response.GetResponseStream();
                    song.Cover = Image.FromStream(stream);
                    bool res = mp3Processor.SaveID3Tag(song);
                    if (res)
                    {
                        AppModel.LogEntry("[SUCCESS] " + song + "  - Cover Saved");
                        App.StatisticLogger.AlbumFound++;
                    }
                }
            }
            catch
            {
                //do nothing
            }

        }
    }
}
